home *** CD-ROM | disk | FTP | other *** search
/ LOGIC Apps / Logic-APPLE_II_APPS.iso / mac / LOGIC Apple II 5.25" Library - ProDOS / PRO081.dsk / MISCELLANEOUS / MISC.02.FAM.ID.txt < prev    next >
Text File  |  2012-02-16  |  30KB  |  510 lines

  1. Apple II
  2. Technical Notes
  3. _____________________________________________________________________________
  4.                                                   Developer Technical Support
  5.  
  6.  
  7. Apple II Miscellaneous
  8. #2:    Apple II Family Identification Routines 2.1
  9.  
  10. Revised by:    Matt Deatherage & Keith Rollin                   November 1988
  11. Revised by:    Pete McDonald                                     January 1986
  12.  
  13. This Technical Note presents a new version of the Apple II Family 
  14. Identification Routine, a sample piece of code which shows how to identify 
  15. various Apple II computers and their memory configurations.
  16. _____________________________________________________________________________
  17.  
  18.  
  19. Why Identification Routines?
  20.  
  21. Although we present the Apple II family identification bytes in Apple II 
  22. Miscellaneous Technical Note #7, many people would prefer a routine they can 
  23. simply plug into their own program and call.  In addition, this routine serves 
  24. as a small piece of sample code, and there is no reason for you to reinvent 
  25. the wheel.
  26.  
  27. Most of the interesting part of the routine consists of identifying the memory 
  28. configuration of the machine.  On an Apple IIe, the routine moves code into 
  29. the zero page to test for the presence of auxiliary memory.  (A IIe with a 
  30. non-extended 80-column card is a configuration still found in many schools 
  31. throughout the country.)
  32.  
  33. The actual identification is done by a table-lookup method.
  34.  
  35.  
  36. What the Routine Returns
  37.  
  38. This version (2.1) of the identification routine returns several things:
  39.  
  40. o    A machine byte, containing one of seven values:
  41.      $00 = Unknown machine
  42.      $01 = Apple ][
  43.      $02 = Apple ][+
  44.      $03 = Apple /// in emulation mode
  45.      $04 = Apple IIe
  46.      $05 = Apple IIc
  47.  
  48.      In addition, if the high bit of the byte is set, the machine is a 
  49.      IIGS or equivalent.  For all current Apple IIGS computers, the 
  50.      value returned in machine is $84 (high bit set to signify Apple 
  51.      IIGS and $04 because it matches the ID bytes of an enhanced Apple 
  52.      IIe).
  53. o    A ROMlevel byte, indicating the revision of the firmware in the 
  54.      machine.  For example, there are currently five revisions of the 
  55.      IIc, two of the IIe (unenhanced and enhanced), and two versions of 
  56.      the IIGS ROM (there will always be some owners who have not yet 
  57.      upgraded).  These versions are identified starting at $01 for the 
  58.      earliest.  Therefore, the current IIc will return ROMlevel = $04, 
  59.      the current IIGS will return ROMlevel = $02, etc.  The routine 
  60.      will also return correct values for future versions of the IIGS, 
  61.      as a convention has been established for future ROM versions of 
  62.      that machine.
  63. o    A memory byte, containing the amount of memory in the machine.  
  64.      This byte only has four values--0 (undefined), 48, 64, and 128.  
  65.      Extra memory in an Apple IIGS, or extra memory in an Apple IIe or 
  66.      IIc Memory Expansion card, is not included.  Programs must take 
  67.      special considerations to use that memory (if available), beyond 
  68.      those considerations required to use the normal 128K of today's 
  69.      IIe and IIc.
  70. o    If running on an Apple IIGS, three word-length fields are also 
  71.      returned.  These are the contents of the registers as returned by 
  72.      the ID routine in the IIGS ROM, and they indicate several things 
  73.      about the machine.  See Apple II Miscellaneous Technical Note #7 
  74.      for more details.
  75.  
  76. In addition to these features, most of the addressing done in the routine is 
  77. by label.  If you wish things to be stored in different places, simply 
  78. changing the labels will often do it.
  79.  
  80.  
  81. Limitations and Improvements
  82.  
  83. As sample code, you might have already guessed that this is not the most 
  84. compact, efficient way of identifying these machines.  Some improvements you 
  85. might incorporate if using these routines include:
  86.  
  87. o    If you are running under ProDOS, you can remove the section that 
  88.      determines how much memory is in the machine (starting at exit, 
  89.      line 127), since the MACHID byte (at $BF98) in ProDOS already 
  90.      contains this information for you.  This change would cut the 
  91.      routine down to less than one page of memory.
  92. o    If you know the ROM is switched in when you call the routine, you 
  93.      can remove the sections which save and restore the language card 
  94.      state.  Be careful in doing so, however, because the memory-
  95.      determination routines switch out the ROM to see if a language 
  96.      card exists.
  97. o    If you need to know if a IIe is a 64K machine with a non-extended 
  98.      80-column card, you may put your own identifying routines in after 
  99.      line 284.  NoAux is only reached if there is an 80-column card but 
  100.      only 64K of memory.
  101.  
  102.  
  103. How It Works
  104.  
  105. The identification routine does the following things:
  106.  
  107. o    Disables interrupts
  108. o    Saves four bytes from the language card areas so they may be restored 
  109.      later
  110. o    Identifies all machines by a table look-up procedure
  111. o    Calls 16-bit ID routine to distinguish IIGS from other machines of any 
  112.      kind, and returns values in appropriate locations if IIGS ID routine 
  113.      returns any useful information in the registers
  114. o    Identifies memory configuration:
  115.      o    If Apple /// emulation, there is 48K
  116.      o    If Apple ][ or ][+, tests for presence of language card and returns 
  117.           64K if present, otherwise, returns 48K
  118.      o    If Apple IIc or IIGS, returns 128K
  119.      o    If Apple IIe, tries to identify auxiliary memory
  120.           o    If reading auxiliary memory, it must be there
  121.           o    If reading alternate zero page, auxiliary memory is present
  122.           o    If none of this is conclusive:
  123.                o    Exchanges a section of the zero page with a section of code 
  124.                     that switches memory banks.  The code executes in the zero
  125.                     page and does not get switched out when we attempt to
  126.                     switch in the auxiliary RAM.
  127.                o    Jumps to relocated code on page zero:
  128.                     o    Switches in auxiliary memory for reading and writing
  129.                     o    Stores a value at $800 and sees if the same value
  130.                          appears at $C00.  If so, no auxiliary memory is
  131.                          present (the non-extended 80-column card has sparse
  132.                          memory mapping which causes $800 and $C00 to be the
  133.                          same location).
  134.                     o    Changes value at $C00 and sees if the value at $800
  135.                          changes as well.  If so, no auxiliary memory.  If not,
  136.                          then there is 128K available
  137.                     o    Switches main memory back in for reading and writing
  138.                o    Puts the zero page back like we found it
  139.           o    Returns memory configuration found (either 64K or 128K)
  140. o    Restores language card and ROM state from four saved bytes
  141. o    Restores interrupt status
  142. o    Returns to caller
  143.  
  144. SOURCE   FILE #01 =>ID2.1
  145.  
  146. 0000:                1           lst   on
  147. ----- NEXT OBJECT FILE NAME IS ID2.1.OBJ                     
  148. 2000:        2000    2           org   $2000
  149. 2000:                3 ********************************************
  150. 2000:                4 *                                          *
  151. 2000:                5 *  Apple II Family Identification Program  *
  152. 2000:                6 *                                          *
  153. 2000:                7 *               Version 2.1                *
  154. 2000:                8 *                                          *
  155. 2000:                9 *              September, 1988             *
  156. 2000:               10 *                                          *
  157. 2000:               11 *  Includes support for revisions to IIc   *
  158. 2000:               12 *  firmware, and IIgs identification too   *
  159. 2000:               13 *                                          *
  160. 2000:               14 ********************************************
  161. 2000:               15 *
  162. 2000:               16 *
  163. 2000:               17 *  First, some global equates for the routine:
  164. 2000:               18 *
  165. 2000:        0001   19 IIplain   equ   $01           ;Apple II
  166. 2000:        0002   20 IIplus    equ   $02           ;Apple II+
  167. 2000:        0003   21 IIIem     equ   $03           ;Apple /// in emulation mode
  168. 2000:        0004   22 IIe       equ   $04           ;Apple IIe
  169. 2000:        0005   23 IIc       equ   $05           ;Apple IIc
  170. 2000:               24 *
  171. 2000:        0001   25 safe      equ   $0001         ;start of code relocated to zp
  172. 2000:        0006   26 location  equ   $06           ;zero page location to use
  173. 2000:               27 *
  174. 2000:        00FB   28 xce       equ   $FB           ;65816 XCE instruction
  175. 2000:               29 *
  176. 2000:        00AA   30 test1     equ   $AA           ;test byte #1
  177. 2000:        0055   31 test2     equ   $55           ;lsr of test1
  178. 2000:        0088   32 test3     equ   $88           ;test byte #3
  179. 2000:        00EE   33 test4     equ   $EE           ;test byte #4
  180. 2000:               34 *
  181. 2000:        0400   35 begpage1  equ   $400          ;beginning of text page 1
  182. 2000:        0800   36 begpage2  equ   $800          ;beginning of text page 2
  183. 2000:        0C00   37 begsprse  equ   $C00          ;byte after text page 2
  184. 2000:               38 *
  185. 2000:        C000   39 clr80col  equ   $C000         ;disable 80-column store
  186. 2000:        C001   40 set80col  equ   $C001         ;enable 80-column store
  187. 2000:        C002   41 rdmainram equ   $C002         ;read main ram
  188. 2000:        C003   42 rdcardram equ   $C003         ;read aux ram
  189. 2000:        C004   43 wrmainram equ   $C004         ;write main ram
  190. 2000:        C005   44 wrcardram equ   $C005         ;write aux ram
  191. 2000:        C013   45 rdramrd   equ   $C013         ;are we reading aux ram?
  192. 2000:        C016   46 rdaltzp   equ   $C016         ;are we reading aux zero page?
  193. 2000:        C018   47 rd80col   equ   $C018         ;are we using 80-columns?
  194. 2000:        C01A   48 rdtext    equ   $C01A         ;read if text is displayed
  195. 2000:        C01C   49 rdpage2   equ   $C01C         ;read if page 2 is displayed
  196. 2000:        C050   50 txtclr    equ   $C050         ;switch in graphics
  197. 2000:        C051   51 txtset    equ   $C051         ;switch in text
  198. 2000:        C054   52 txtpage1  equ   $C054         ;switch in page 1
  199. 2000:        C055   53 txtpage2  equ   $C055         ;switch in page 2
  200. 2000:        C080   54 ramin     equ   $C080         ;read LC bank 2, write protected
  201. 2000:        C081   55 romin     equ   $C081         ;read ROM, 2 reads write enable LC
  202. 2000:        C08B   56 lcbank1   equ   $C08B         ;LC bank 1 enable 
  203. 2000:               57 *
  204. 2000:        E000   58 lc1       equ   $E000         ;bytes to save for LC
  205. 2000:        D000   59 lc2       equ   $D000         ;save/restore routine
  206. 2000:        D400   60 lc3       equ   $D400
  207. 2000:        D800   61 lc4       equ   $D800
  208. 2000:               62 *
  209. 2000:        FE1F   63 idroutine equ   $FE1F         ;IIgs id routine
  210. 2000:               64 *
  211. 2000:               65 *  Start by saving the state of the language card banks and
  212. 2000:               66 *  by switching in main ROM.
  213. 2000:               67 *
  214. 2000:08             68 strt      php                 ;save the processor state
  215. 2001:78             69           sei                 ;before disabling interrupts
  216. 2002:AD 00 E0       70           lda   lc1           ;save four bytes from
  217. 2005:8D F1 21       71           sta   save          ;ROM/RAM area for later
  218. 2008:AD 00 D0       72           lda   lc2           ;restoring of RAM/ROM
  219. 200B:8D F2 21       73           sta   save+1        ;to original condition
  220. 200E:AD 00 D4       74           lda   lc3
  221. 2011:8D F3 21       75           sta   save+2
  222. 2014:AD 00 D8       76           lda   lc4
  223. 2017:8D F4 21       77           sta   save+3
  224. 201A:AD 81 C0       78           lda   $C081         ;read ROM
  225. 201D:AD 81 C0       79           lda   $C081
  226. 2020:A9 00          80           lda   #0            ;start by assuming unknown machine
  227. 2022:8D E8 21       81           sta   machine
  228. 2025:8D E9 21       82           sta   romlevel
  229. 2028:               83 *
  230. 2028:A5 06          84 IdStart   lda   location      ;save zero page locations
  231. 202A:8D F5 21       85           sta   save+4        ;for later restoration
  232. 202D:A5 07          86           lda   location+1
  233. 202F:8D F6 21       87           sta   save+5
  234. 2032:A9 FB          88           lda   #$FB          ;all ID bytes are in page $FB
  235. 2034:85 07          89           sta   location+1    ;save in zero page as high byte
  236. 2036:A2 00          90           ldx   #0            ;init pointer to start of ID table
  237. 2038:BD F7 21       91 loop      lda   IDTable,x     ;get the machine we are testing for
  238. 203B:8D E8 21       92           sta   machine       ;and save it
  239. 203E:BD F8 21       93           lda   IDTable+1,x   ;get the ROM level we are testing for
  240. 2041:8D E9 21       94           sta   romlevel      ;and save it
  241. 2044:0D E8 21       95           ora   machine       ;are both zero?
  242. 2047:F0 1C   2065   96           beq   matched       ;yes - at end of list - leave
  243. 2049:               97 *
  244. 2049:E8             98 loop2     inx                 ;bump index to loc/byte pair to test
  245. 204A:E8             99           inx
  246. 204B:BD F7 21      100           lda   IDTable,x     ;get the byte that should be in ROM
  247. 204E:F0 15   2065  101           beq   matched       ;if zero, we're at end of list
  248. 2050:85 06         102           sta   location      ;save in zero page
  249. 2052:              103 *
  250. 2052:A0 00         104           ldy   #0            ;init index for indirect addressing
  251. 2054:BD F8 21      105           lda   IDTable+1,x   ;get the byte that should be in ROM
  252. 2057:D1 06         106           cmp   (Location),y  ;is it there?
  253. 2059:F0 EE   2049  107           beq   loop2         ;yes, so keep on looping
  254. 205B:              108 *
  255. 205B:E8            109 loop3     inx                 ;we didn't match.Scoot to the end of the
  256. 205C:E8            110           inx                 ;line in the ID table so we can start
  257. 205D:BD F7 21      111           lda   IDTable,x     ;checking for another machine
  258. 2060:D0 F9   205B  112           bne   loop3
  259. 2062:E8            113           inx                  ;point to start of next line
  260. 2063:D0 D3   2038  114           bne   loop          ;should always be taken
  261. 2065:              115 *
  262. 2065:        2065  116 matched   equ   * 
  263. 2065:              117 *
  264. 2065:              118 *  Here we check the 16-bit ID routine at $FE1F.  If it
  265. 2065:              119 *  returns with carry clear, we call it again in 16-bit
  266. 2065:              120 *  mode to provide more information on the machine.
  267. 2065:              121 *
  268. 2065:38            122 idIIgs    sec                 ;set the carry bit
  269. 2066:20 1F FE      123           jsr   idroutine     ;Apple IIgs ID Routine
  270. 2069:90 03   206E  124           bcc   idIIgs2       ;it's a IIgs or equivalent
  271. 206B:4C A2 20      125           jmp   exit          ;nope, go check memory
  272. 206E:AD E8 21      126 idIIgs2   lda   machine       ;get the value for machine
  273. 2071:09 80         127           ora   #$80          ;and set the high bit
  274. 2073:8D E8 21      128           sta   machine       ;put it back
  275. 2076:18            129           clc                 ;get ready to switch into native mode
  276. 2077:FB            130           dfb   xce           ;this is a 65816 XCE instruction
  277. 2078:08            131           php                 ;save the processor status
  278. 2079:C2 30         132           dfb   $C2,$30       ;REP 30, sets 16-bit registers
  279. 207B:20 1F FE      133           jsr   $FE1f         ;call the ID routine again
  280. 207E:8D EB 21      134           sta   IIgsA         ;16-bit store!
  281. 2081:8E ED 21      135           stx   IIgsX         ;16-bit store!
  282. 2084:8C EF 21      136           sty   IIgsY         ;16-bit store!
  283. 2087:28            137           plp                 ;restores 8-bit registers
  284. 2088:FB            138           dfb   xce           ;switches back to whatever it was before
  285. 2089:              139 *
  286. 2089:AC EF 21      140           ldy   IIgsY         ;get the ROM vers number (starts at 0)
  287. 208C:C0 02         141           cpy   #$02          ;is it ROM 01 or 00?
  288. 208E:B0 01   2091  142           bcs   idIIgs3       ;if not, don't increment
  289. 2090:C8            143           iny                 ;bump it up for romlevel
  290. 2091:8C E9 21      144 idIIgs3   sty   romlevel      ;and put it there
  291. 2094:C0 01         145           cpy   #$01          ;is it the first ROM?
  292. 2096:D0 0A   20A2  146           bne   IIgsOut       ;no, go on with things
  293. 2098:AD F0 21      147           lda   IIgsY+1       ;check the other byte too
  294. 209B:D0 05   20A2  148           bne   IIgsOut       ;nope, it's a IIgs successor
  295. 209D:A9 7F         149           lda   #$7F          ;fix faulty ROM 00 on the IIgs
  296. 209F:8D EB 21      150           sta   IIgsA
  297. 20A2:        20A2  151 IIgsOut   equ   *
  298. 20A2:              152 *
  299. 20A2:              153 ******************************************
  300. 20A2:              154 * This part of the code checks for the   *
  301. 20A2:              155 * memory configuration of the machine.   *
  302. 20A2:              156 * If it's a IIgs, we've already stored   *
  303. 20A2:              157 * the total memory from above.  If it's  *
  304. 20A2:              158 * a IIc, we know it's 128K; if it's a    *
  305. 20A2:              159 * ][+, we know it's at least 48K and     *
  306. 20A2:              160 * maybe 64K.  We won't check for less    *
  307. 20A2:              161 * than 48K, since that's a really rare   *
  308. 20A2:              162 * circumstance.                          *
  309. 20A2:              163 ******************************************
  310. 20A2:              164 *
  311. 20A2:AD E8 21      165 exit      lda   machine       ;get the machine kind
  312. 20A5:30 14   20BB  166           bmi   exit128       ;it's a 16-bit machine (has 128K)
  313. 20A7:C9 05         167           cmp   #IIc          ;is it a IIc?
  314. 20A9:F0 10   20BB  168           beq   exit128       ;yup, it's got 128K
  315. 20AB:C9 04         169           cmp   #IIe          ;is it a IIe?
  316. 20AD:D0 03   20B2  170           bne   contexit      ;yes, go muck with aux memory
  317. 20AF:4C 4E 21      171           jmp   muckaux
  318. 20B2:C9 03         172 contexit  cmp   #IIIem        ;is it a /// in emulation?
  319. 20B4:D0 6E   2124  173           bne   exitII        ;nope, it's a ][ or ][+
  320. 20B6:A9 30         174           lda   #48           ;/// emulation has 48K
  321. 20B8:4C BD 20      175           jmp   exita
  322. 20BB:A9 80         176 exit128   lda   #128          ;128K 
  323. 20BD:8D EA 21      177 exita     sta   memory
  324. 20C0:AD 00 E0      178 exit1     lda   lc1           ;time to restore the LC
  325. 20C3:CD F1 21      179           cmp   save          ;if all 4 bytes are the same
  326. 20C6:D0 18   20E0  180           bne   exit2         ;then LC was never on so
  327. 20C8:AD 00 D0      181           lda   lc2           ;do nothing
  328. 20CB:CD F2 21      182           cmp   save+1
  329. 20CE:D0 10   20E0  183           bne   exit2
  330. 20D0:AD 00 D4      184           lda   lc3
  331. 20D3:CD F3 21      185           cmp   save+2
  332. 20D6:D0 08   20E0  186           bne   exit2
  333. 20D8:AD 00 D8      187           lda   lc4
  334. 20DB:CD F4 21      188           cmp   save+3
  335. 20DE:F0 38   2118  189           beq   exit6
  336. 20E0:AD 88 C0      190 exit2     lda   $C088         ;no match! so turn first LC
  337. 20E3:AD 00 E0      191           lda   lc1           ;bank on and check
  338. 20E6:CD F1 21      192           cmp   save
  339. 20E9:F0 06   20F1  193           beq   exit3
  340. 20EB:AD 80 C0      194           lda   $C080
  341. 20EE:4C 18 21      195           jmp   exit6
  342. 20F1:AD 00 D0      196 exit3     lda   lc2
  343. 20F4:CD F2 21      197           cmp   save+1        ;if all locations check
  344. 20F7:F0 06   20FF  198           beq   exit4         ;then do more more else
  345. 20F9:AD 80 C0      199           lda   $C080         ;turn on bank 2
  346. 20FC:4C 18 21      200           jmp   exit6
  347. 20FF:AD 00 D4      201 exit4     lda   lc3           ;check second byte in bank 1
  348. 2102:CD F3 21      202           cmp   save+2
  349. 2105:F0 06   210D  203           beq   exit5
  350. 2107:AD 80 C0      204           lda   $C080         ;select bank 2
  351. 210A:4C 18 21      205           jmp   exit6
  352. 210D:AD 00 D8      206 exit5     lda   lc4           ;check third byte in bank 1
  353. 2110:CD F4 21      207           cmp   save+3
  354. 2113:F0 03   2118  208           beq   exit6
  355. 2115:AD 80 C0      209           lda   $C080         ;select bank 2
  356. 2118:28            210 exit6     plp                 ;restore interrupt status
  357. 2119:AD F5 21      211           lda   save+4        ;put zero page back
  358. 211C:85 06         212           sta   location
  359. 211E:AD F6 21      213           lda   save+5        ;like we found it
  360. 2121:85 07         214           sta   location+1
  361. 2123:60            215           rts                 ;and go home.
  362. 2124:              216 *
  363. 2124:AD 8B C0      217 exitII    lda   lcbank1       ;force in language card
  364. 2127:AD 8B C0      218           lda   lcbank1       ;bank 1
  365. 212A:AE 00 D0      219           ldx   lc2           ;save the byte there
  366. 212D:A9 AA         220           lda   #test1        ;use this as a test byte
  367. 212F:8D 00 D0      221           sta   lc2
  368. 2132:4D 00 D0      222           eor   lc2           ;if the same, should return zero
  369. 2135:D0 12   2149  223           bne   noLC
  370. 2137:4E 00 D0      224           lsr   lc2           ;check twice just to be sure
  371. 213A:A9 55         225           lda   #test2        ;this is the shifted value
  372. 213C:4D 00 D0      226           eor   lc2           ;here's the second check
  373. 213F:D0 08   2149  227           bne   noLC
  374. 2141:8E 00 D0      228           stx   lc2           ;put it back!
  375. 2144:A9 40         229           lda   #64           ;there's 64K here
  376. 2146:4C BD 20      230           jmp   exita
  377. 2149:A9 30         231 noLC      lda   #48           ;no restore - no LC!
  378. 214B:4C BD 20      232           jmp   exita         ;and get out of here
  379. 214E:              233 *
  380. 214E:AE 1A C0      234 muckaux   ldx   rdtext        ;remember graphics in X
  381. 2151:AD 1C C0      235           lda   rdpage2       ;remember current video display
  382. 2154:0A            236           asl   A             ;in the carry bit 
  383. 2155:A9 88         237           lda   #test3        ;another test character
  384. 2157:2C 18 C0      238           bit   rd80col       ;remember video mode in N
  385. 215A:8D 01 C0      239           sta   set80col      ;enable 80-column store
  386. 215D:08            240           php                 ;save N and C flags
  387. 215E:8D 55 C0      241           sta   txtpage2      ;set page two
  388. 2161:8D 51 C0      242           sta   txtset        ;set text
  389. 2164:AC 00 04      243           ldy   begpage1      ;save first character
  390. 2167:8D 00 04      244           sta   begpage1      ;and replace it with test character
  391. 216A:AD 00 04      245           lda   begpage1      ;get it back
  392. 216D:8C 00 04      246           sty   begpage1      ;and put back what was there
  393. 2170:28            247           plp
  394. 2171:B0 08   217B  248           bcs   muck2         ;stay in page 2
  395. 2173:8D 54 C0      249           sta   txtpage1      ;restore page 1
  396. 2176:30 03   217B  250 muck1     bmi   muck2         ;stay in 80-columns
  397. 2178:8D 00 C0      251           sta   $c000         ;turn off 80-columns
  398. 217B:A8            252 muck2     tay                 ;save returned character
  399. 217C:8A            253           txa                 ;get graphics/text setting
  400. 217D:30 03   2182  254           bmi   muck3
  401. 217F:8D 50 C0      255           sta   txtclr        ;turn graphics back on
  402. 2182:C0 88         256 muck3     cpy   #test3        ;finally compare it
  403. 2184:D0 2F   21B5  257           bne   nocard        ;no 80-column card!
  404. 2186:AD 13 C0      258           lda   rdramrd       ;is aux memory being read?
  405. 2189:30 2F   21BA  259           bmi   muck128       ;yup, there's 128K!
  406. 218B:AD 16 C0      260           lda   rdaltzp       ;is aux zero page used?
  407. 218E:30 2A   21BA  261           bmi   muck128       ;yup!
  408. 2190:A0 2A         262           ldy   #done-start
  409. 2192:BE BC 21      263 move      ldx   start-1,y     ;swap section of zero page
  410. 2195:B9 00 00      264           lda   safe-1,y      ;code needings safe location during
  411. 2198:96 00         265           stx   safe-1,y      ;reading of aux mem
  412. 219A:99 BC 21      266           sta   start-1,Y
  413. 219D:88            267           dey
  414. 219E:D0 F2   2192  268           bne   move
  415. 21A0:4C 01 00      269           jmp   safe          ;jump to safe ground
  416. 21A3:08            270 back      php                 ;save status
  417. 21A4:A0 2A         271           ldy   #done-start   ;move zero page back
  418. 21A6:B9 BC 21      272 move2     lda   start-1,y
  419. 21A9:99 00 00      273           sta   safe-1,y
  420. 21AC:88            274           dey
  421. 21AD:D0 F7   21A6  275           bne   move2
  422. 21AF:68            276           pla
  423. 21B0:B0 03   21B5  277           bcs   noaux
  424. 21B2:4C BA 21      278 isaux     jmp   muck128       ;there is 128K
  425. 21B5:              279 *
  426. 21B5:              280 *  You can put your own routine at "noaux" if you wish to
  427. 21B5:              281 *  distinguish between 64K without an 80-column card and
  428. 21B5:              282 *  64K with an 80-column card.
  429. 21B5:              283 *
  430. 21B5:        21B5  284 noaux     equ   *
  431. 21B5:A9 40         285 nocard    lda   #64           ;only 64K
  432. 21B7:4C BD 20      286           jmp   exita
  433. 21BA:4C BB 20      287 muck128   jmp   exit128       ;there's 128K
  434. 21BD:              288 *
  435. 21BD:              289 *  This is the routine run in the safe area not affected
  436. 21BD:              290 *  by bank-switching the main and aux RAM.
  437. 21BD:              291 *
  438. 21BD:A9 EE         292 start     lda   #test4        ;yet another test byte
  439. 21BF:8D 05 C0      293           sta   wrcardram     ;write to aux while on main zero page
  440. 21C2:8D 03 C0      294           sta   rdcardram     ;read aux ram as well
  441. 21C5:8D 00 08      295           sta   begpage2      ;check for sparse memory mapping
  442. 21C8:AD 00 0C      296           lda   begsprse      ;if sparse, these will be the same 
  443. 21CB:C9 EE         297           cmp   #test4        ;value since they're 1K apart
  444. 21CD:D0 0E   21DD  298           bne   auxmem        ;yup, there's 128K!
  445. 21CF:0E 00 0C      299           asl   begsprse      ;may have been lucky so we'll
  446. 21D2:AD 00 08      300           lda   begpage2      ;change the value and see what happens
  447. 21D5:CD 00 0C      301           cmp   begsprse
  448. 21D8:D0 03   21DD  302           bne   auxmem
  449. 21DA:38            303           sec                 ;oops, no auxiliary memory
  450. 21DB:B0 01   21DE  304           bcs   goback
  451. 21DD:18            305 auxmem    clc
  452. 21DE:8D 04 C0      306 goback    sta   wrmainram     ;write main RAM
  453. 21E1:8D 02 C0      307           sta   rdmainram     ;read main RAM
  454. 21E4:4C A3 21      308           jmp   back          ;continue with program in main mem
  455. 21E7:EA            309 done      nop                 ;end of relocated program marker
  456. 21E8:              310 *
  457. 21E8:              311 *
  458. 21E8:              312 *  The storage locations for the returned machine ID:
  459. 21E8:              313 *
  460. 21E8:00            314 machine   dfb   $00           ;the type of Apple II
  461. 21E9:00            315 romlevel  dfb   $00           ;which revision of the machine
  462. 21EA:00            316 memory    dfb   $00           ;how much memory (up to 128K)
  463. 21EB:00 00         317 IIgsA     dw    $0000         ;16-bit field
  464. 21ED:00 00         318 IIgsX     dw    $0000         ;16-bit field
  465. 21EF:00 00         319 IIgsY     dw    $0000         ;16-bit field
  466. 21F1:00 00 00 00   320 save      dfb   0,0,0,0,0,0   ;six bytes for saved data
  467. 21F7:01 01 B3 38   321 IDTable   dfb   1,1,$B3,$38,$00 ;Apple ][
  468. 21FC:02 01 B3 EA   322           dfb   2,1,$B3,$EA,$1E,$AD,$00 ;Apple ][+
  469. 2203:03 01 B3 EA   323           dfb   3,1,$B3,$EA,$1E,$8A,$00 ;Apple /// (emulation)
  470. 220A:04 01 B3 06   324           dfb   4,1,$B3,$06,$C0,$EA,$00 ;Apple IIe (original)
  471. 2211:04 02 B3 06   325           dfb   4,2,$B3,$06,$C0,$E0,$00 ;Apple IIe (enhanced)
  472. 2218:05 01 B3 06   326           dfb   5,1,$B3,$06,$C0,$00,$BF,$FF,$00 ;Apple IIc (original)
  473. 2221:05 02 B3 06   327           dfb   5,2,$B3,$06,$C0,$00,$BF,$00,$00 ;Apple IIc (3.5 ROM)
  474. 222A:05 03 B3 06   328           dfb   5,3,$B3,$06,$C0,$00,$BF,$03,$00 ;Apple IIc (Mem. Exp)
  475. 2233:05 04 B3 06   329           dfb   5,4,$B3,$06,$C0,$00,$BF,$04,$00 ;Apple IIc (Rev. Mem. 
  476. Exp.)
  477. 223C:05 05 B3 06   330           dfb   5,5,$B3,$06,$C0,$00,$BF,$05,$00 ;Apple IIc Plus
  478. 2245:00 00         331           dfb   0,0           ;end of table
  479.  
  480.  21DD AUXMEM         21A3 BACK           0400 BEGPAGE1       0800 BEGPAGE2      
  481.  0C00 BEGSPRSE      ?C000 CLR80COL       20B2 CONTEXIT       21E7 DONE          
  482.  20E0 EXIT2          20A2 EXIT           20BB EXIT128       ?20C0 EXIT1         
  483.  20F1 EXIT3          20FF EXIT4          210D EXIT5          2118 EXIT6         
  484.  20BD EXITA          2124 EXITII         21DE GOBACK        ?2065 IDIIGS        
  485.  206E IDIIGS2        2091 IDIIGS3        FE1F IDROUTINE     ?2028 IDSTART       
  486.  21F7 IDTABLE          05 IIC              04 IIE            21EB IIGSA         
  487.  20A2 IIGSOUT        21ED IIGSX          21EF IIGSY            03 IIIEM         
  488. ?  01 IIPLAIN       ?  02 IIPLUS        ?21B2 ISAUX          E000 LC1           
  489.  D000 LC2            D400 LC3            D800 LC4            C08B LCBANK1       
  490.    06 LOCATION       2038 LOOP           2049 LOOP2          205B LOOP3         
  491.  21E8 MACHINE        2065 MATCHED        21EA MEMORY         21A6 MOVE2         
  492.  2192 MOVE           21BA MUCK128       ?2176 MUCK1          217B MUCK2         
  493.  2182 MUCK3          214E MUCKAUX        21B5 NOAUX          21B5 NOCARD        
  494.  2149 NOLC          ?C080 RAMIN          C018 RD80COL        C016 RDALTZP       
  495.  C003 RDCARDRAM      C002 RDMAINRAM      C01C RDPAGE2        C013 RDRAMRD       
  496.  C01A RDTEXT        ?C081 ROMIN          21E9 ROMLEVEL         01 SAFE          
  497.  21F1 SAVE           C001 SET80COL       21BD START         ?2000 STRT          
  498.    AA TEST1            55 TEST2            88 TEST3            EE TEST4         
  499.  C050 TXTCLR         C054 TXTPAGE1       C055 TXTPAGE2       C051 TXTSET        
  500.  C005 WRCARDRAM      C004 WRMAINRAM        FB XCE           
  501. ** SUCCESSFUL ASSEMBLY := NO ERRORS
  502. ** ASSEMBLER CREATED ON 15-JAN-84 21:28 
  503. ** TOTAL LINES ASSEMBLED   331 
  504. ** FREE SPACE PAGE COUNT   81 
  505.  
  506.  
  507. Further Reference
  508. o    Apple II Miscellaneous Technical Note #7, Apple II Family Identification
  509.  
  510.